<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>改变this的指向（call apply bind ）</title>
</head>
<body>
    <!-- 
        他们的共同点：
            都能改变一个this指向的作用域
     -->

     <!-- 
        ☆ call 指定调用函数中的this指向（很少使用这个）
            他的第一个参数是要指向的this，后面的参数通过 , 隔开
      -->
      <script>
        const obj = {
            uname : 'luochun'
        }

        function fn(x,y){
            console.log(this);  // 指向的是window
        }
        // 通过call调用的函数可以直接运行,后面的参数通过逗号隔开，他是函数的形参
        // ☆ 注意：这时的参数不是一一对应的，第一个参数是this的指向
        fn.call(obj,20,30)
      </script>


      <!-- 
        ☆ apply  可以调用函数，同时指定被调用函数的this，apply主要跟数组有关系，比如使用Math.max()求数组的最大值
            他的参数通过数组指定，后面跟的是一个数组,并且必须是一个数组
       -->

       <script>
            const obj1 = {
                age : 18
            }
            function fu(x,y){
                console.log(this);
                console.log(x+y);
            }
            // 调用函数
            // 改变this的指向
            // 他的参数必须是一个数组，通过形参来接
            fu.apply(obj1,[1,2])
            // 返回值 本身就是在调用函数，所以他的返回值就是函数的返回值

            // 使用场景：求数组的最大值
            const arr = [100,44,77]
            const max = Math.max.apply(Math,arr)
            const min = Math.min.apply(null,arr) // 没有this指向也可以写null

            // 可以通过这种方式进行求最大值
            // 目前我知道有三种：自己遍历，通过apply ， Math方法
            // 通过Math
            const max1 = Math.max(...arr) // 需要展开的数据
       </script>

       <!-- 
            ☆☆ 重点bind（） 方法不会调用函数，但是能改变函数内部this的指向
            语法： fun.bind(thisArg,arg1,arg2) 和call很相似
            返回值：由指定的this值和初始化参数改造的原函数拷贝（新函数）---- 返回的是一个函数，但是this指向改变了
            因此当我们只想改变this，并不想调用这个函数的时候，可以使用bind，比如改变定时器内部的this指向
        -->

        <script>
            const obj2 = {
                age:18
            }
            function func(){
                console.log(this);
            }
            // bind 不会调用函数
            // 能改变this的指向
            const newobj= func.bind(obj2)
        </script>

        <!-- 
            需求案例 ：
                有一个按钮，点击里面就禁用，2秒钟之后就开启
        -->
        <button>发送短信</button>
        <script>
            const btn = document.querySelector('button')
            // btn.addEventListener('click',function(){
            //     this.disabled = true 
            //     setTimeout(function(){
            //         // 执行不了，因为这个this指向的是window
            //         this.disabled = false
            //         // 在后面改变函数的this指向
            //     }.bind(this),2000)
            // })
            btn.addEventListener('click',function(){
                this.disabled = true 
                setTimeout(()=>{
                    this.disabled = false
                },2000)
            })
        </script>
</body>
</html> 